using System;
using System.Collections.Generic;
using System.Net.NetworkInformation;
using BaseAmd.BaseData;
using BaseAmd.Common;
using BaseAmd.Ret;
using Catastrophe.Common.ObjM;

namespace BaseAmd.BaseDevice
{
	public abstract class BaseDeviceAmd
	{
		public const int PingErrorCode = -101;

		private ControlLogic<bool> _onLineStatusMonitor;

		protected ControlLogic<int> RunStateMonitor;

		protected int DefaultRunState = 0;

		public virtual bool IsConnected { get; set; }

		public int Timeout { get; set; } = 3000;


		public DeviceStatusEnum? DeviceStatusNow { get; set; }

		public bool IsOnLineStatusUpdate
		{
			get
			{
				bool flag = this._onLineStatusMonitor.IsDataChange(this.IsConnected);
				if (flag)
				{
					string deviceName = this.DeviceName;
					string deviceNo = this.DeviceNo;
				}
				return flag;
			}
		}

		public string DeviceName { get; set; }

		public string DeviceNo { get; set; }

		public abstract OperateAmdRet Start();

		public abstract void SetValid(bool flag);

		public virtual GOperateAmdRet<Dictionary<string, object>> GetDicVarRet()
		{
			return new GOperateAmdRet<Dictionary<string, object>>
			{
				Message = "Not Implemented Method"
			};
		}

		protected abstract void UpdateOnLineState(bool isConnected);

		protected abstract void DeviceStatusMonitor();

		public BaseDeviceAmd()
		{
			this._onLineStatusMonitor = new ControlLogic<bool>(t: false);
			this.RunStateMonitor = new ControlLogic<int>(this.DefaultRunState);
		}

		public Dictionary<T, DbCompareRetEnum> GetCompareRet<T>(List<T> dbList, List<T> readList, List<string> pkColList, List<string> compareNotIncludeCols, Action<T> actDuplicate = null, Func<T, T> funcBeforeDelete = null, Func<T, T> funcBeforeUpdate = null)
		{
			Dictionary<T, DbCompareRetEnum> dictionary = new Dictionary<T, DbCompareRetEnum>();
			List<string> list = new List<string>();
			List<string> list2 = new List<string>();
			List<T> list3 = new List<T>();
			foreach (T read in readList)
			{
				string pkValue = ExtendUtil.GetPkValue(read, pkColList);
				if (!list2.Contains(pkValue))
				{
					list2.Add(pkValue);
				}
				else
				{
					list3.Add(read);
				}
			}
			foreach (T item in list3)
			{
				readList.Remove(item);
			}
			foreach (T db in dbList)
			{
				string pkValue2 = ExtendUtil.GetPkValue(db, pkColList);
				bool flag = true;
				if (!list.Contains(pkValue2))
				{
					list.Add(pkValue2);
					foreach (T read2 in readList)
					{
						string pkValue3 = ExtendUtil.GetPkValue(read2, pkColList);
						if (pkValue2 == pkValue3)
						{
							flag = false;
							break;
						}
					}
				}
				else
				{
					actDuplicate?.Invoke(db);
				}
				if (flag)
				{
					T key = db;
					if (funcBeforeDelete != null)
					{
						key = funcBeforeDelete(db);
					}
					dictionary.Add(key, DbCompareRetEnum.Delete);
				}
			}
			foreach (T read3 in readList)
			{
				string pkValue4 = ExtendUtil.GetPkValue(read3, pkColList);
				T val = ExtendUtil.QueryFirst(dbList, pkValue4, pkColList);
				DbCompareRetEnum dbCompareRetEnum = ExtendUtil.EntityCompare(read3, val, compareNotIncludeCols);
				if (dbCompareRetEnum != 0)
				{
					T val2 = ((val == null) ? read3 : val);
					if (funcBeforeUpdate != null)
					{
						val2 = funcBeforeUpdate(val2);
					}
					if (!dictionary.ContainsKey(val2))
					{
						dictionary.Add(val2, dbCompareRetEnum);
					}
				}
			}
			return dictionary;
		}

		protected virtual OperateAmdRet ClearAlarm()
		{
			return new OperateAmdRet
			{
				Message = "Not Implemented Method"
			};
		}

		protected virtual OperateAmdRet AlarmCommit<T>(Dictionary<T, DbCompareRetEnum> dic) where T : BaseAlarmEntity
		{
			return new OperateAmdRet
			{
				Message = "Not Implemented Method"
			};
		}

		protected virtual OperateAmdRet UpdateAlarmEndTime()
		{
			return new OperateAmdRet
			{
				Message = "Not Implemented Method"
			};
		}

		public OperateAmdRet Ping(string ip, int timeout = 3000)
		{
			OperateAmdRet operateAmdRet = new OperateAmdRet();
			Ping ping = new Ping();
			try
			{
				PingReply pingReply = ping.Send(ip, timeout);
				if (pingReply != null && pingReply.Status == IPStatus.Success)
				{
					operateAmdRet.Success = true;
					operateAmdRet.ErrorCode = -101;
					return operateAmdRet;
				}
				operateAmdRet.Message = pingReply?.Status.ToString() ?? "ping failed!";
				return operateAmdRet;
			}
			catch (Exception ex)
			{
				operateAmdRet.Message = ex.ToString();
				return operateAmdRet;
			}
		}
	}
}
